package com.pixelengine.Task26Oee;

import com.pixelengine.HBasePeHelperCppConnector;
import com.pixelengine.TileComputeResult;
import org.apache.tomcat.jni.Directory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.websocket.Decoder;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
public class WorkbenchAPIsController {

    //获取全部产品信息
    @ResponseBody
    @RequestMapping(value = "/productinfo", method = RequestMethod.GET)
    @CrossOrigin(origins = "*")
    public ProductInfos.ProductInfo[] getProductInfo() {
        return ProductInfos.getInstance().product_array;
    }

    //获取产品日期时间数组
    @ResponseBody
    @RequestMapping(value = "/productdtarr", method = RequestMethod.GET)
    @CrossOrigin(origins = "*")
    public String[] getPdtDtArr(@RequestParam("dsname") String dsname) {
        ArrayList<String> dtarr = new ArrayList<String>();
        ProductInfos.ProductInfo pdtinfo = ProductInfos.getInstance().productDict.get(dsname) ;
        if( pdtinfo==null ) {
            String[] a = new String[0];
            return a;
        }else{
            if( pdtinfo.hTableName.contentEquals("COG") ) {
                String subdir = TheConfig.getInstance().cog_dir + "/" + pdtinfo.pdtname ;
                File folder = new File(subdir);
                if( folder.exists() ) {
                    File[] listOfFiles = folder.listFiles();
                    for (File file : listOfFiles) {
                        if (file.isFile()) {
                            dtarr.add( file.getName().substring(0,file.getName().length()-4) ) ;//remove .tif
                        }
                    }
                }
            }else {
                String subdir = TheConfig.getInstance().tile_file_dir + "/" + pdtinfo.pdtname ;
                File folder = new File(subdir);
                if( folder.exists() ) {
                    File[] listOfFiles = folder.listFiles();
                    for (File file : listOfFiles) {
                        if (file.isDirectory()) {
                            dtarr.add( file.getName() ) ;
                        }
                    }
                }
            }
            Collections.sort(dtarr);
            String[] a = new String[dtarr.size()];
            a = dtarr.toArray(a);
            return a;
        }
    }


    //获取感兴趣区列表
    @ResponseBody
    @RequestMapping(value = "/rois", method = RequestMethod.GET)
    @CrossOrigin(origins = "*")
    public String[] getRois() throws IOException {
        ArrayList<String> arr = new ArrayList<String>();
        String subdir = TheConfig.getInstance().roi_dir   ;
        File folder = new File(subdir);
        if( folder.exists() ) {
            List<Path> allFiles = new ArrayList<>();
            listAllFiles(folder.toPath(), allFiles);
            for(Path path1 : allFiles) {
                arr.add( path1.toString().replace(subdir ,"")) ;
            }
        }
        Collections.sort(arr);
        String[] a = new String[arr.size()];
        a = arr.toArray(a);
        return a;
    }

    private static void listAllFiles(Path currentPath, List<Path> allFiles)
            throws IOException
    {
        try (DirectoryStream<Path> stream = Files.newDirectoryStream(currentPath))
        {
            for (Path entry : stream) {
                if (Files.isDirectory(entry)) {
                    listAllFiles(entry, allFiles);
                } else {
                    allFiles.add(entry);
                }
            }
        }
    }

    //获取产品日期时间数组
    @ResponseBody
    @RequestMapping(value = "/scripts", method = RequestMethod.GET)
    @CrossOrigin(origins = "*")
    public String[] getScripts() throws IOException {
        ArrayList<String> arr = new ArrayList<String>();
        String subdir = TheConfig.getInstance().script_dir   ;
        File folder = new File(subdir);
        if( folder.exists() ) {
            List<Path> allFiles = new ArrayList<>();
            listAllFiles(folder.toPath(), allFiles);
            for(Path path1 : allFiles) {
                if( path1.toString().endsWith(".js")) {
                    arr.add( path1.toString().replace(subdir ,"")) ;
                }
            }
        }
        Collections.sort(arr);
        String[] a = new String[arr.size()];
        a = arr.toArray(a);
        return a;
    }

    //获取背景矢量数据
    @ResponseBody
    @RequestMapping(value = "/bglines", method = RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE )
    @CrossOrigin(origins = "*")
    public String getBgLines() throws IOException {
        String fname = TheConfig.getInstance().bg_lines;
        byte[] geojsonData = Files.readAllBytes(Paths.get(fname));
        String geojsonText = new String(geojsonData);
        return geojsonText;
    }

    //获取一个脚本文件
    @ResponseBody
    @RequestMapping(value = "/script", method = RequestMethod.GET )
    @CrossOrigin(origins = "*")
    public String getScriptText(@RequestParam("jsname") String jsname) throws IOException {
        String fname = TheConfig.getInstance().script_dir+ "/" + jsname ;
        byte[] data = Files.readAllBytes(Paths.get(fname));
        String text = new String(data);
        return text;
    }


    //保存一个ROI Geojson
    @ResponseBody
    @RequestMapping(value = "/saveroi", method = RequestMethod.POST, produces=MediaType.TEXT_PLAIN_VALUE )
    @CrossOrigin(origins = "*")
    public String saveRoi(@RequestParam("fname") String fname,@RequestParam("geojson") String geojson) throws IOException {
        System.out.println(fname);
        //建立子目录，写入文件
        String roifullname = TheConfig.getInstance().roi_dir + "/" + fname;
        File file = new File(roifullname);
        String parentDir = file.getParent() ;
        File pdir = new File(parentDir) ;
        if( pdir.exists() == false) {
            pdir.mkdirs();
        }
        file.createNewFile();
        Files.write( Paths.get(roifullname) , geojson.getBytes()) ;
        String text = new String("good");
        return text;
    }

    //保存一个脚本
    @ResponseBody
    @RequestMapping(value = "/savejs", method = RequestMethod.POST, produces=MediaType.TEXT_PLAIN_VALUE )
    @CrossOrigin(origins = "*")
    public String saveJs(@RequestParam("fname") String fname,@RequestParam("text") String text) throws IOException {
        System.out.println(fname);
        //建立子目录，写入文件
        String jsfullname = TheConfig.getInstance().script_dir + "/" + fname;
        File file = new File(jsfullname);
        String parentDir = file.getParent() ;
        File pdir = new File(parentDir) ;
        if( pdir.exists() == false) {
            pdir.mkdirs();
        }
        file.createNewFile();
        Files.write( Paths.get(jsfullname) , text.getBytes()) ;
        String text2 = new String("good");
        return text2;
    }


    //绘制方案（渲染方案）列表
    @ResponseBody
    @RequestMapping(value = "/styles", method = RequestMethod.GET)
    @CrossOrigin(origins = "*")
    public String[] getStyles() throws IOException {
        ArrayList<String> arr = new ArrayList<String>();
        String subdir = TheConfig.getInstance().style_dir   ;
        File folder = new File(subdir);
        if( folder.exists() ) {
            List<Path> allFiles = new ArrayList<>();
            listAllFiles(folder.toPath(), allFiles);
            for(Path path1 : allFiles) {
                arr.add( path1.toString().replace(subdir ,"")) ;
            }
        }
        Collections.sort(arr);
        String[] a = new String[arr.size()];
        a = arr.toArray(a);
        return a;
    }

    //获取一个绘制方案文件
    @ResponseBody
    @RequestMapping(value = "/style", method = RequestMethod.GET )
    @CrossOrigin(origins = "*")
    public String getStyleText(@RequestParam("name") String name) throws IOException {
        String fname = TheConfig.getInstance().style_dir+ name ;
        byte[] data = Files.readAllBytes(Paths.get(fname));
        String text = new String(data);
        return text;
    }


    //保存一个绘制方案
    @ResponseBody
    @RequestMapping(value = "/savestyle", method = RequestMethod.POST, produces=MediaType.TEXT_PLAIN_VALUE )
    @CrossOrigin(origins = "*")
    public String saveStyle(@RequestParam("fname") String fname,@RequestParam("text") String text) throws IOException {
        System.out.println(fname);
        //建立子目录，写入文件
        String fullname = TheConfig.getInstance().style_dir + fname;
        File file = new File(fullname);
        String parentDir = file.getParent() ;
        File pdir = new File(parentDir) ;
        if( pdir.exists() == false) {
            pdir.mkdirs();
        }
        file.createNewFile();
        Files.write( Paths.get(fullname) , text.getBytes()) ;
        String text2 = new String("good");
        return text2;
    }

    //获取脚本执行日志
    @ResponseBody
    @RequestMapping(value = "/logs", method = RequestMethod.GET, produces=MediaType.TEXT_PLAIN_VALUE )
    @CrossOrigin(origins = "*")
    public String getlogs(
            HttpServletRequest request,
            ModelMap model
    ) throws IOException {
        StringBuilder requestURL = new StringBuilder(request.getRequestURL().toString());
        String queryString = request.getQueryString();
        if (queryString == null) {
            System.out.println( requestURL.toString() );
        } else {
            System.out.println( requestURL.append('?').append(queryString).toString());
        }
        Enumeration<String> params = request.getParameterNames();
        HashMap<String,String> lowerParams = new HashMap<String,String>();
        while (params.hasMoreElements())
        {
            String name1 = params.nextElement();
            String value1 = request.getParameter(name1) ;
            lowerParams.put( name1.toLowerCase() , value1) ;
        }
        String name = lowerParams.get("name") ;//
        String dtstr = lowerParams.get("datetime")  ;//
        String styleId = lowerParams.get("styleid") ;// '', null are treated as no styleid.
        String sduiJsonStr = lowerParams.get("sdui") ;// '','null','{}' are all treated as no sdui.
        try{
            //load script contents
            String scriptContent = null;
            try {
                if(scriptContent==null) {
                    String scriptFilename=TheConfig.getInstance().script_dir+name ;//this name include .js
                    String tcontent = new String(
                            Files.readAllBytes(Paths.get(scriptFilename)),
                            StandardCharsets.UTF_8);
                    scriptContent = tcontent;
                }
            }finally {
            }
            if( scriptContent==null ) {
                throw new Exception("failed to load script content.");
            }
            int tilez =0;
            int tiley =0;
            int tilex =0;
            String extraStr = "{\"datetime\":"+dtstr+"}" ;
            HBasePeHelperCppConnector cc = new HBasePeHelperCppConnector();
            if( hasSduiDeclearation(scriptContent) && sduiJsonStr!=null ){
                if( sduiJsonStr.compareTo("null") != 0
                        && sduiJsonStr.compareTo("") != 0
                        && sduiJsonStr.compareTo("{}")!=0
                ){
                    String sduiJsonStr2 = "\nsdui=" + sduiJsonStr + ";\n" ;
                    scriptContent = scriptContent.replace("function main(" , sduiJsonStr2 + "function main(") ;
                }
            }
            String styleJsonText = "" ;
            if( styleId==null || styleId.equals("") || styleId.equals("null") ) {
                //no style
            }else{
                byte[] ssdata = TheConfig.getInstance().getStyleData(styleId);
                if( ssdata!=null ) {
                    styleJsonText = new String(ssdata);
                }
            }
            //不做裁剪直接渲染png
            TileComputeResult res1 = cc.RunScriptForTileWithRenderWithExtra(
                    "com/pixelengine/TileFilePixelEngineHelper",
                    scriptContent,
                    styleJsonText,
                    extraStr,
                    tilez,
                    tiley,
                    tilex
            ) ;
            Date date = new Date() ;
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ;
            String logDtStr = df.format(date).toString();
            String logText = logDtStr +"---------\n" + res1.log+ "\n" ;
            return logText;
        }catch (Exception ex){
            Date date = new Date() ;
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ;
            String logDtStr = df.format(date).toString();
            String logText = logDtStr +"---------\n" + ex.getMessage()+ "\n" ;
            return logText;
        }
    }

    ///remove \n \r space \t
    private String removeAllNoMeansChar(String text){
        String t1 = text.replace(" ","") ;
        t1 = t1.replace("\n","") ;
        t1 = t1.replace("\r","") ;
        t1 = t1.replace("\t","") ;
        return t1 ;
    }

    /// check script text if contains sdui declearation.
    private boolean hasSduiDeclearation(String jsText){
        String t1 = removeAllNoMeansChar(jsText) ;
        if( t1.contains("letsdui={") || t1.contains("varsdui={")){
            return true ;
        }else{
            return false ;
        }
    }
}
